home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 10
/
FM Towns Free Software Collection 10.iso
/
ms_dos
/
tool
/
make
/
src
/
make.c
< prev
next >
Wrap
Text File
|
1995-02-28
|
25KB
|
1,201 lines
/*****************************************************
make.c
1993.7.29 make by Ken
******************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifndef LSIC
#include <sys/types.h>
#endif
#include <sys/stat.h>
#include "defs.h"
#define SBDFALC 8
#define MKDFALC 16
char *version = "%s version 0.12 1995.01.26 Nanno-NET(Ken)\n";
int debug_flag = 0;
int all_target_flag = FALSE;
ENVPTR *env_tab[HASH_SIZE];
TAGPTR *tag_tab[HASH_SIZE];
TAGPTR *tag_top = NULL;
TAGPTR *tag_now = NULL;
TAGPTR *tag_list = NULL;
RULPTR *rule_top = NULL;
SUBPTR *rule_now = NULL;
CMDPTR *make_top = NULL;
CMDPTR *make_btm = NULL;
static SUBPTR *sub_free = NULL;
static MAKPTR *mk_free = NULL;
extern int optind;
extern char *optarg;
static char tmp_buff[STRLEN + 2];
static char *def_rule[] = {
#ifdef UNIX
# include "default.c"
#else
"CC=cc",
"CFLAGS=-O",
".SUFFIXES: . .lzh .zip .zoo .lzs .gz .z .Z",
".SUFFIXES: .dvi .tex .ref",
".SUFFIXES: .lst .map .lnk .sym .mak .def",
".SUFFIXES: .exe .exp .exg .com .rex",
".SUFFIXES: .lib .obj .dlg .asm",
".SUFFIXES: .o .a .c .cc .p .f .r .y .l .s .h",
".c.obj:",
" $(CC) $(CFLAGS) -c $<",
#endif
NULL
};
char *trim(char *str)
{
char *p;
while ( isspace(*str) )
str++;
for ( p = str + strlen(str) ; p > str && isspace(*(p - 1)) ; )
p--;
*p = '\0';
return str;
}
char *basename(char *buf, char *str)
{
char *p;
char *s;
if ( (p = strrchr(str, '/')) == NULL &&
(p = strrchr(str, '\\')) == NULL &&
(p = strrchr(str, ':')) == NULL )
p = str;
#ifdef MAKE_OLD
if ( p != str )
str = p + 1;
#endif
if ( (p = strrchr(p, '.')) == NULL ) {
for ( p = str ; *p != '\0' ; p++ )
;
}
s = buf;
while ( *str != '\0' && str < p )
*(s++) = *(str++);
*s = '\0';
return buf;
}
int hash_calc(char *p)
{
int hs = 0;
while ( *p != '\0' )
hs = hs * 31 + *(p++);
return (hs & HASH_MASK);
}
char *get_env(char *name)
{
int hs;
ENVPTR *ep;
hs = hash_calc(name);
for ( ep = env_tab[hs] ; ep != NULL ; ep = ep->ev_next ) {
if ( strcmp(name, ep->ev_name) == 0 )
return ep->ev_para;
}
return "";
}
char *set_env(char *name, char *para)
{
int hs;
ENVPTR *ep;
hs = hash_calc(name);
for ( ep = env_tab[hs] ; ep != NULL ; ep = ep->ev_next ) {
if ( strcmp(name, ep->ev_name) == 0 ) {
FREE(ep->ev_para);
if ( (ep->ev_para = STRDUP(para)) == NULL ) {
fprintf(stderr, "strdup malloc error '%s'\n", para);
exit(2);
}
return ep->ev_para;
}
}
if ( (ep = (ENVPTR *)MALLOC(sizeof(ENVPTR) + strlen(name))) == NULL ) {
fprintf(stderr, "envptr malloc error\n");
exit(2);
}
if ( (ep->ev_para = STRDUP(para)) == NULL ) {
fprintf(stderr, "strdup malloc error '%s'\n", para);
exit(2);
}
strcpy(ep->ev_name, name);
ep->ev_next = env_tab[hs];
env_tab[hs] = ep;
return ep->ev_para;
}
char *get_macro(char *str)
{
int n, len;
char *p, *s;
char tmp[80 + 2];
char rep[STRLEN + 2];
char dmy[STRLEN + 2];
for ( n = 0 ; *str != '\0' && *str != ':' ; ) {
if ( n < 80 )
tmp[n++] = *(str++);
}
tmp[n] = '\0';
if ( strchr(tmp, '*') != NULL || strchr(tmp, '?') != NULL ) {
n = 0;
while ( (p = wild_file(tmp)) != NULL ) {
if ( n < STRLEN )
dmy[n++] = ' ';
while ( n < STRLEN && *p != '\0' )
dmy[n++] = *(p++);
}
dmy[n] = '\0';
p = dmy + 1;
} else
p = get_env(tmp);
if ( *str == ':' ) {
str++;
for ( n = 0 ; *str != '\0' && *str != '=' ; ) {
if ( n < 80 )
tmp[n++] = *(str++);
}
tmp[n] = '\0';
if ( *str == '=' )
str++;
len = strlen(tmp);
n = 0;
while ( n < STRLEN && *p != '\0' ) {
if ( strncmp(p, tmp, len) == 0 ) {
p += len;
for ( s = str ; n < STRLEN && *s != '\0' ; )
rep[n++] = *(s++);
} else
rep[n++] = *(p++);
}
rep[n] = '\0';
p = rep;
}
return STRDUP(p);
}
char *macro(char *buf, char *str, int max)
{
int n = 0;
int ch;
char *t;
char *b;
static int nest = 0;
while ( *str != '\0' && n < max ) {
switch(*str) {
case '$':
str++;
switch(*(str++)) {
case '$':
buf[n++] = '$';
break;
case '*':
t = get_env("*"); /* target base name */
goto STRCPY;
case '<': /* depend name */
t = get_env("<");
goto STRCPY;
case '@': /* target name */
t = get_env("@");
goto STRCPY;
case '?': /* all depend name */
t = get_env("?");
STRCPY:
while ( *t != '\0' && n < max )
buf[n++] = *(t++);
break;
case '(':
ch = ')';
goto MACRO;
case '{':
ch = '}';
MACRO:
if ( (b = strchr(str, ch)) != NULL ) {
*b = '\0';
if ( ++nest >= NEST_MAX ) {
fprintf(stderr, "deep nesting macro '%s'\n", str);
exit(2);
}
t = get_macro(str);
*(b++) = ch;
str = b;
macro(buf + n, t, max - n);
while ( buf[n] != '\0' )
n++;
FREE(t);
nest--;
break;
}
default:
str -= 2;
buf[n++] = *(str++);
break;
}
break;
default:
buf[n++] = *(str++);
break;
}
}
buf[n] = '\0';
return buf;
}
int env_load(char *name)
{
int n;
char *para;
char *p;
char buf[STRLEN + 2];
if ( (para = strchr(name, '=')) == NULL )
return ERR;
if ( para > name && *(para - 1) == '+' ) {
*(para - 1) = '\0';
para++;
name = trim(name);
p = get_env(name);
for ( n = 0 ; n < STRLEN && *p != '\0' ; )
buf[n++] = *(p++);
while ( n < STRLEN && *para != '\0' )
buf[n++] = *(para++);
buf[n] = '\0';
para = trim(buf);
set_env(name, para);
} else {
*(para++) = '\0';
name = trim(name);
para = trim(para);
set_env(name, para);
}
if ( debug_flag > 1 )
fprintf(stderr, "set %s = %s\n", name, para);
return FALSE;
}
TAGPTR *set_target(char *file)
{
int hs;
TAGPTR *tp;
hs = hash_calc(file);
for ( tp = tag_tab[hs] ; tp != NULL ; tp = tp->tg_next ) {
if ( strcmp(file, tp->tg_file) == 0 )
return tp;
}
if ( (tp = (TAGPTR *)MALLOC(sizeof(TAGPTR) + strlen(file))) == NULL ) {
fprintf(stderr, "tagptr malloc error '%s'\n", file);
exit(2);
}
strcpy(tp->tg_file, file);
tp->tg_list = NULL;
tp->tg_link = NULL;
tp->tg_cmds = NULL;
tp->tg_status = TAG_NOCHECK;
tp->tg_time = NOTIME;
tp->tg_next = tag_tab[hs];
tag_tab[hs] = tp;
return tp;
}
TAGPTR *get_target(char *file)
{
int hs;
TAGPTR *tp;
hs = hash_calc(file);
for ( tp = tag_tab[hs] ; tp != NULL ; tp = tp->tg_next ) {
if ( strcmp(file ,tp->tg_file) == 0 )
return tp;
}
return NULL;
}
MAKPTR *makptr_alloc(char *file)
{
int n;
MAKPTR *mp;
TAGPTR *tp;
if ( mk_free == NULL ) {
if ( (mp = (MAKPTR *)MALLOC(sizeof(MAKPTR) * MKDFALC )) == NULL ) {
fprintf(stderr, "makptr malloc error '%s'\n", file);
exit(2);
}
for ( n = 0 ; n < MKDFALC ; n++ ) {
mp->mk_next = mk_free;
mk_free = mp;
mp++;
}
}
mp = mk_free;
mk_free = mp->mk_next;
tp = set_target(file);
mp->mk_file = tp->tg_file;
mp->mk_next = NULL;
return mp;
}
void makptr_free(MAKPTR *mp)
{
mp->mk_next = mk_free;
mk_free = mp;
}
MAKPTR *makptr_wild(char *file)
{
MAKPTR *mp;
MAKPTR top;
char *p;
if ( strchr(file, '*') != NULL || strchr(file, '?') != NULL ) {
top.mk_next = NULL;
mp = ⊤
while ( (p = wild_file(file)) != NULL ) {
mp->mk_next = makptr_alloc(p);
mp = mp->mk_next;
}
return top.mk_next;
} else
return makptr_alloc(file);
}
MAKPTR *depend_link(char **ptr)
{
char *p;
char *s;
MAKPTR *mp = NULL;
p = *ptr;
LOOP:
while ( isspace(*p) )
p++;
if ( *p != '\0' ) {
for ( s = p ; *s != '\0' ; s++ ) {
if ( isspace(*s) )
break;
}
if ( *s == '\0' )
mp = makptr_wild(p);
else {
*s = '\0';
mp = makptr_wild(p);
*(s++) = ' ';
}
p = s;
if ( mp == NULL )
goto LOOP;
}
*ptr = p;
return mp;
}
void target_alloc(char *file, char *para)
{
MAKPTR *mp, *bp, *ap;
TAGPTR *tp;
char tmp[STRLEN + 2];
rule_now = NULL;
tp = get_target(file);
tag_now = set_target(file);
if ( tp == NULL ) {
tag_now->tg_list = tag_list;
tag_list = tag_now;
}
set_env("@", tag_now->tg_file);
set_env("*", basename(tmp, tag_now->tg_file));
set_env("<", "");
set_env("?", "");
para = macro(tmp, para, STRLEN);
if ( tag_top == NULL )
tag_top = tag_now;
while ( (mp = depend_link(¶)) != NULL ) {
do {
ap = bp = tag_now->tg_link;
while ( bp != NULL ) {
if ( strcmp(bp->mk_file, mp->mk_file) == 0 ) {
if ( ap == bp )
tag_now->tg_link = bp->mk_next;
else
ap->mk_next = bp->mk_next;
makptr_free(bp);
break;
}
ap = bp;
bp = bp->mk_next;
}
if ( debug_flag > 1 )
fprintf(stderr, "target %s : %s\n", file, mp->mk_file);
bp = mp->mk_next;
mp->mk_next = tag_now->tg_link;
tag_now->tg_link = mp;
mp = bp;
} while ( mp != NULL );
}
if ( tag_now->tg_link == NULL ) {
if ( debug_flag > 1 )
fprintf(stderr, "target %s :\n", file);
tag_now->tg_status = TAG_DEFEXEC;
}
}
void target_link(char *file, char *para)
{
int n;
char *p, *s;
char tmp[STRLEN + 2];
while ( *file != '\0' ) {
for ( p = file ; *p != '\0' ; p++ ) {
if ( isspace(*p) ) {
*(p++) = '\0';
break;
}
}
if ( strchr(file, '*') != NULL || strchr(file, '?') != NULL ) {
n = 0;
while ( (s = wild_file(file)) != NULL ) {
if ( n < STRLEN )
tmp[n++] = ' ';
while ( n < STRLEN && *s != '\0' )
tmp[n++] = *(s++);
}
tmp[n] = '\0';
target_link(tmp + 1, para);
} else
target_alloc(file, para);
file = p;
while ( isspace(*file) )
file++;
}
}
void suff_init(char *str)
{
char *p;
RULPTR *rp;
while ( *str != '\0' ) {
while ( isspace(*str) )
str++;
p = str;
while ( !isspace(*str) && *str != '\0' )
str++;
if ( isspace(*str) )
*(str++) = '\0';
if ( *p == '\0' )
continue;
else if ( strcmp(p, ".") == 0 )
p++;
for ( rp = rule_top ; rp != NULL ; rp = rp->rl_next ) {
if ( strcmp(p, rp->rl_tag) == 0 )
break;
}
if ( rp == NULL ) {
if ( (rp = (RULPTR *)MALLOC(sizeof(RULPTR) +
strlen(p))) == NULL ) {
fprintf(stderr, "rulptr malloc error '%s'\n", p);
exit(2);
}
strcpy(rp->rl_tag, p);
rp->rl_flag = FALSE;
rp->rl_link = NULL;
rp->rl_next = rule_top;
rule_top = rp;
if ( debug_flag > 1 )
fprintf(stderr, "suffix %%%s\n", rp->rl_tag);
}
}
}
SUBPTR *subptr_alloc(char *name)
{
int n;
SUBPTR *sp;
if ( sub_free == NULL ) {
if ( (sp = (SUBPTR *)MALLOC(sizeof(SUBPTR) * SBDFALC)) == NULL )
return NULL;
for ( n = 0 ; n < SBDFALC ; n++ ) {
sp->sb_next = sub_free;
sub_free = sp;
sp++;
}
}
sp = sub_free;
sub_free = sp->sb_next;
return sp;
}
int suff_check(char *str) /* .c.o */
{
int n;
RULPTR *tp; /* .o */
RULPTR *dp; /* .c */
SUBPTR *sp;
SUBPTR *ap;
for ( dp = rule_top ; dp != NULL ; dp = dp->rl_next ) {
n = strlen(dp->rl_tag);
if ( n > 0 && strncmp(str, dp->rl_tag, n) == 0 ) {
for ( tp = rule_top ; tp != NULL ; tp = tp->rl_next ) {
if ( strcmp(str + n, tp->rl_tag) == 0 )
goto RULESET;
}
}
}
return FALSE;
RULESET:
for ( ap = sp = tp->rl_link ; sp != NULL ; ) {
if ( strcmp(dp->rl_tag, sp->sb_dep) == 0 ) {
if ( ap != sp ) {
ap->sb_next = sp->sb_next;
sp->sb_next = tp->rl_link;
tp->rl_link = sp;
}
sp->sb_cmds = NULL;
break;
}
ap = sp;
sp = sp->sb_next;
}
if ( sp == NULL ) {
if ( (sp = subptr_alloc(dp->rl_tag)) == NULL ) {
fprintf(stderr, "subptr malloc error '%s'\n", dp->rl_tag);
exit(2);
}
sp->sb_dep = dp->rl_tag;
sp->sb_cmds = NULL;
sp->sb_next = tp->rl_link;
tp->rl_link = sp;
}
tag_now = NULL;
rule_now = sp;
if ( debug_flag > 1 )
fprintf(stderr, "rule %%%s : %%%s\n", tp->rl_tag, dp->rl_tag);
return TRUE;
}
int make_load(char *file)
{
char *para;
set_env("*", "");
set_env("@", "");
set_env("<", "");
set_env("?", "");
file = macro(tmp_buff, file, STRLEN);
if ( (para = strchr(file, ':')) == NULL )
return ERR;
else if ( strcmp(file, ".SUFFIXES") == 0 )
para = file + 9;
*(para++) = '\0';
file = trim(file);
para = trim(para);
if ( *para == ':' )
para = trim(++para);
if ( suff_check(file) )
return FALSE;
else if ( strcmp(file, ".SUFFIXES") == 0 )
suff_init(para);
else
target_link(file, para);
return FALSE;
}
int cmds_load(CMDPTR *cp)
{
char *p;
if ( tag_now != NULL ) {
cp->cd_next = tag_now->tg_cmds;
tag_now->tg_cmds = cp;
} else if ( rule_now != NULL ) {
cp->cd_next = rule_now->sb_cmds;
rule_now->sb_cmds = cp;
} else
return ERR;
p = cp->cd_exec;
while ( isspace(*p) )
p++;
if ( p > cp->cd_exec )
strcpy(cp->cd_exec, p);
if ( debug_flag > 1 )
fprintf(stderr, "cmds : %s\n", cp->cd_exec);
return FALSE;
}
int make_parse()
{
int st;
CMDPTR *cp, *tp;
suff_init(get_env("SUFFIXES"));
for ( cp = tp = make_top ; cp != NULL ; cp = tp ) {
tp = cp->cd_next;
if ( isspace(cp->cd_exec[0]) )
st = cmds_load(cp);
else {
st = make_load(cp->cd_exec);
FREE(cp);
}
if ( st ) {
fprintf(stderr, "make parse error '%s'\n", cp->cd_exec);
exit(2);
}
}
tag_now = NULL;
rule_now = NULL;
return FALSE;
}
int make_save(char *str)
{
CMDPTR *cp;
if ( (cp = (CMDPTR *)MALLOC(sizeof(CMDPTR) + strlen(str))) == NULL ) {
fprintf(stderr, "make load malloc error '%s'\n", str);
exit(2);
}
strcpy(cp->cd_exec, str);
cp->cd_next = NULL;
if ( make_top == NULL )
make_top = cp;
else
make_btm->cd_next = cp;
make_btm = cp;
return FALSE;
}
int parse_load(char *para)
{
char *str;
str = para;
while ( isspace(*str) )
str++;
if ( *str == '\0' || *str == '\n' || *str == '#' )
return FALSE;
while ( isalnum(*str) || *str == '_' || *str == '.' )
str++;
while ( isspace(*str) )
str++;
if ( *str == '=' )
return env_load(para);
else
return make_save(para);
}
int file_load(char *file)
{
int len = 0;
int line = 0;
FILE *fp;
char *p;
if ( (fp = fopen(file, "r")) == NULL )
return ERR;
if ( debug_flag > 0 )
fprintf(stderr, "rule file load '%s'\n", file);
while ( fgets(tmp_buff + len, STRLEN - len, fp) != NULL ) {
line++;
if ( (p = strchr(tmp_buff, '\n')) != NULL )
*p = '\0';
if ( (p = strchr(tmp_buff, '#')) != NULL )
*p = '\0';
p = tmp_buff + strlen(tmp_buff) - 1;
if ( p >= tmp_buff && *p == '\\' ) {
len = p - tmp_buff;
continue;
}
len = 0;
if ( parse_load(tmp_buff) ) {
fprintf(stderr, "parse error '%s' in %d line\n", file, line);
fprintf(stderr, "%s\n", tmp_buff);
exit(2);
}
}
fclose(fp);
return FALSE;
}
/**************************************************************/
int suff_cmp(char *file, char *ptn)
{
int n;
char *p;
if ( *ptn == '\0' ) {
if ( (p = strrchr(file, '/')) == NULL &&
(p = strrchr(file, '\\')) == NULL )
p = file;
if ( strchr(p, '.') == NULL )
return strlen(file);
else
return (-1);
} else if ( (n = strlen(file) - strlen(ptn)) > 0 &&
strcmp(file + n, ptn) == 0 )
return n;
else
return (-1);
}
int rule_exec(TAGPTR *tag, char *file)
{
int n, i;
RULPTR *rp;
SUBPTR *sp;
TAGPTR *tp;
MAKPTR *mp;
struct stat st;
time_t ti = NOTIME;
char tmp[STRLEN + 2];
static int deps = 0;
deps++;
if ( tag != NULL )
file = tag->tg_file;
for ( rp = rule_top ; rp != NULL ; rp = rp->rl_next ) {
if ( rp->rl_flag == FALSE &&
(n = suff_cmp(file, rp->rl_tag)) > 0 ) {
rp->rl_flag = TRUE;
strcpy(tmp, file);
if ( tag != NULL ) {
for ( sp = rp->rl_link ; sp != NULL ; sp = sp->sb_next ) {
strcpy(tmp + n, sp->sb_dep);
for ( mp = tag->tg_link ; mp != NULL ; mp = mp->mk_next ) {
if ( strcmp(tmp, mp->mk_file) == 0 )
goto RULEMACH;
}
}
}
for ( sp = rp->rl_link ; sp != NULL ; sp = sp->sb_next ) {
strcpy(tmp + n, sp->sb_dep);
if ( debug_flag > 1 ) {
for ( i = 0 ; i < deps ; i++ )
fprintf(stderr, " ");
fprintf(stderr, "chk rule %s ? %s\n", file, tmp);
}
if ( !stat(tmp, &st) ) {
ti = st.st_mtime;
goto RULEMACH;
} else if ( (tp = get_target(tmp)) != NULL &&
rule_exec(tp, NULL) )
goto RULEMACH;
else if ( rule_exec(NULL, tmp) )
goto RULEMACH;
}
rp->rl_flag = FALSE;
break;
}
}
deps--;
return FALSE;
RULEMACH:
if ( debug_flag > 1 ) {
for ( n = 0 ; n < deps ; n++ )
fprintf(stderr, " ");
fprintf(stderr, "def rule %s -> %s\n", file, tmp);
}
target_alloc(file, tmp);
tp = get_target(tmp);
tp->tg_time = ti;
if ( tag_now->tg_cmds == NULL )
tag_now->tg_cmds = sp->sb_cmds;
rp->rl_flag = FALSE;
deps--;
return TRUE;
}
void cmds_exec(CMDPTR *cp)
{
int n;
char *p;
int noecho = FALSE;
int noerrret = FALSE;
int useshell = FALSE;
if ( cp == NULL )
return;
cmds_exec(cp->cd_next);
p = macro(tmp_buff, cp->cd_exec, STRLEN);
if ( debug_flag > 1 )
fprintf(stderr, "exec %s\n", p);
for ( ; ; ) {
if ( *p == '@' ) {
p++;
noecho = TRUE;
} else if ( *p == '-' ) {
p++;
noerrret = TRUE;
} else if ( *p == '+' ) {
p++;
useshell = TRUE;
} else
break;
}
if ( !noecho )
fprintf(stderr, "%s\n", p);
if ( debug_flag <= 1 && (n = SYSTEM(useshell, p)) && !noerrret ) {
fprintf(stderr, "*** error code %d %s\n", n, p);
exit(1);
}
}
int make_exec(TAGPTR *tp)
{
int rt = FALSE;
int n;
MAKPTR *mp;
TAGPTR *dp;
char *p;
struct stat st;
static int deps = 0;
if ( tp == NULL || (tp->tg_status & TAG_UPDATE) )
return FALSE;
deps++;
tp->tg_status |= TAG_UPDATE;
if ( (tp->tg_status & TAG_DEFEXEC) )
rt = TRUE;
if ( tp->tg_cmds == NULL )
rule_exec(tp, NULL);
for ( mp = tp->tg_link ; mp != NULL ; mp = mp->mk_next ) {
dp = get_target(mp->mk_file);
make_exec(dp);
if ( tp->tg_time == NOTIME ) {
if ( stat(tp->tg_file, &st) )
tp->tg_time = NOFILE;
else
tp->tg_time = st.st_mtime;
}
if ( dp->tg_time == NOTIME ) {
if ( stat(dp->tg_file, &st) ) {
fprintf(stderr, "not found depend file '%s'\n", dp->tg_file);
exit(1);
}
dp->tg_time = st.st_mtime;
}
if ( debug_flag > 0 ) {
for ( n = 0 ; n < deps ; n++ )
fprintf(stderr, " ");
fprintf(stderr, "check %s(%ld) ? %s(%ld) %s\n",
tp->tg_file, tp->tg_time,
dp->tg_file, dp->tg_time,
tp->tg_time < dp->tg_time ? "domake" : "");
}
if ( tp->tg_time < dp->tg_time )
rt = TRUE;
}
if ( rt ) {
set_env("*", basename(tmp_buff, tp->tg_file));
set_env("@", tp->tg_file);
if ( (mp = tp->tg_link) != NULL ) {
set_env("<", mp->mk_file);
n = 0;
for ( ; ; ) {
p = mp->mk_file;
while ( *p != '\0' && n < STRLEN )
tmp_buff[n++] = *(p++);
if ( (mp = mp->mk_next) == NULL )
break;
tmp_buff[n++] = ' ';
}
tmp_buff[n] = '\0';
set_env("?", tmp_buff);
} else {
set_env("<", "");
set_env("?", "");
}
cmds_exec(tp->tg_cmds);
time(&(tp->tg_time));
}
deps--;
return rt;
}
void make_list(TAGPTR *tp)
{
if ( tp != NULL ) {
make_list(tp->tg_list);
make_exec(tp);
}
}
void free_memory()
{
int n;
int a;
long l = 0L;
char *tmp[32];
a = (16 * 1024);
n = 0;
for ( ; n < 32 && a > 4 ; ) {
if ( (tmp[n] = (char *)MALLOC(a)) == NULL )
a /= 2;
else {
l += a;
n++;
}
}
for ( a = 0 ; a < n ; a++ )
FREE(tmp[a]);
fprintf(stderr, "free memory size %ld\n", l);
}
void usage(char *prog)
{
#ifdef MAKE_OLD
fprintf(stderr, "Usage: %s [-dv] [-t <Target>] [Makefile...]\n", prog);
#else
fprintf(stderr, "Usage: %s [-a] [-dv] [-f <Makefile>] [Target...]\n", prog);
#endif
}
int main(int ac, char *av[], char *ev[])
{
int n;
int mx = 1;
int mkc = 0;
char *mkv[10];
int tgc = 0;
char *tgv[10];
char *p;
TAGPTR *tp;
for ( ; ; ) {
while ( (n = getopt(ac, av, "advf:t:D:V")) != EOF ) {
switch(n) {
case 'a':
all_target_flag = TRUE;
break;
case 'd':
debug_flag += 2;
break;
case 'v':
debug_flag += 1;
break;
case 'f':
if ( mkc >= 10 ) {
fprintf(stderr, "makefile overflow '%s'\n", optarg);
exit(2);
}
mkv[mkc++] = optarg;
break;
case 't':
if ( tgc >= 10 ) {
fprintf(stderr, "target overflow '%s'\n", optarg);
exit(2);
}
tgv[tgc++] = optarg;
break;
case 'D':
if ( env_load(strcpy(tmp_buff, optarg)) )
set_env(optarg, "");
break;
case 'V':
fprintf(stderr, version, av[0]);
return 0;
default:
usage(av[0]);
exit(2);
}
}
if ( optind >= ac )
break;
av[mx++] = av[optind++];
}
for ( n = 0 ; def_rule[n] != NULL ; n++ )
parse_load(strcpy(tmp_buff, def_rule[n]));
set_env("MAKE", av[0]);
tmp_buff[0] = '\0';
if ( all_target_flag )
strcpy(tmp_buff, "-a");
if ( debug_flag >= 2 )
strcat(tmp_buff, " -d");
if ( debug_flag >= 1 )
strcat(tmp_buff, " -v");
set_env("MAKEFLAGS", tmp_buff);
if ( (p = get_env("MAKEFILE")) != NULL && *p != '\0' )
file_load(p);
for ( n = 0 ; ev[n] != NULL ; n++ )
env_load(strcpy(tmp_buff, ev[n]));
#ifdef MAKE_OLD
for ( n = 1 ; n < mx ; n++ ) {
if ( strchr(av[n], '=') == NULL ) {
if ( mkc >= 10 ) {
fprintf(stderr, "makefile overflow '%s'\n", av[n]);
exit(2);
}
mkv[mkc++] = av[n];
}
}
#endif
if ( mkc > 0 ) {
for ( n = 0 ; n < mkc ; n++ ) {
if ( file_load(mkv[n]) ) {
fprintf(stderr, "can't open '%s'\n", mkv[n]);
exit(1);
}
}
} else {
if ( file_load("Makefile") && file_load("makefile") ) {
fprintf(stderr, "can't open makefile\n");
exit(1);
}
}
for ( n = 1 ; n < mx ; n++ ) {
if ( env_load(strcpy(tmp_buff, av[n])) ) {
#ifndef MAKE_OLD
if ( tgc >= 10 ) {
fprintf(stderr, "target overflow '%s'\n", av[n]);
exit(2);
}
tgv[tgc++] = av[n];
#endif
}
}
make_parse();
if ( tgc > 0 ) {
for ( n = 0 ; n < tgc ; n++ ) {
if ( (tp = get_target(tgv[n])) == NULL ) {
fprintf(stderr, "No rule to make target `%s'.\n", tgv[n]);
exit(2);
} else if ( !make_exec(tp) )
fprintf(stderr, "`%s' is up to date.\n", tp->tg_file);
}
} else if ( all_target_flag ) {
make_list(tag_list);
} else {
#ifdef MAKE_OLD
make_list(tag_list);
#else
if ( !make_exec(tag_top) )
fprintf(stderr, "`%s' is up to date.\n", tag_top->tg_file);
#endif
}
if ( debug_flag > 1 )
free_memory();
return 0;
}